﻿#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <linux/if.h>
#include <linux/if_tun.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <errno.h>
#include <linux/if_ether.h>
#include <linux/ip.h>  
#include <linux/tcp.h>
#include <errno.h>


#include "connect_socket.h"
#include "hashmap.h"
#include "log.h"

int tun_open(const char* dev) {
    struct ifreq ifr;
    int fd = open("/dev/net/tun", O_RDWR);
    if (fd < 0) {
        perror("Opening /dev/net/tun");
        return -1;
    }

    memset(&ifr, 0, sizeof(ifr));
    ifr.ifr_flags = IFF_TUN | IFF_NO_PI; // TUN device without packet info
    strncpy(ifr.ifr_name, dev, IFNAMSIZ);

    if (ioctl(fd, TUNSETIFF, (void*)&ifr) < 0) {
        perror("TUNSETIFF");
        close(fd);
        return -1;
    }

    // 激活接口
    int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
    if (sockfd < 0) {
        perror("Socket creation failed");
        close(fd);
        return -1;
    }

    if (ioctl(sockfd, SIOCGIFFLAGS, &ifr) < 0) {
        perror("Getting interface flags failed");
        close(sockfd);
        close(fd);
        return -1;
    }

    ifr.ifr_flags |= IFF_UP; // 设置接口为 UP
    if (ioctl(sockfd, SIOCSIFFLAGS, &ifr) < 0) {
        perror("Setting interface flags failed");
        close(sockfd);
        close(fd);
        return -1;
    }

    close(sockfd);
    return fd;
}

int set_ip_and_mask(const char* dev, const char* ip, const char* mask) {
    int sockfd;
    struct ifreq ifr;

    sockfd = socket(AF_INET, SOCK_DGRAM, 0);
    if (sockfd < 0) {
        perror("Socket creation failed");
        return -1;
    }

    // 设置 IP 地址
    memset(&ifr, 0, sizeof(ifr));
    strncpy(ifr.ifr_name, dev, IFNAMSIZ);
    struct sockaddr_in* addr = (struct sockaddr_in*)&ifr.ifr_addr;
    addr->sin_family = AF_INET;
    inet_pton(AF_INET, ip, &addr->sin_addr);

    if (ioctl(sockfd, SIOCSIFADDR, &ifr) < 0) {
        perror("Setting IP address failed");
        close(sockfd);
        return -1;
    }

    // 设置子网掩码
    inet_pton(AF_INET, mask, &addr->sin_addr);
    if (ioctl(sockfd, SIOCSIFNETMASK, &ifr) < 0) {
        perror("Setting subnet mask failed");
        close(sockfd);
        return -1;
    }

    close(sockfd);
    return 0;
}

void tun_listen() {
   
    log_print_level();

    char buffer[2048];
    const char* dev = "tun0";
    const char* ip = "183.2.172.1";     // 设置所需的 IP 地址
    //const char* ip = "192.168.1.1";     // 设置所需的 IP 地址
    const char* mask = "255.255.255.0"; // 设置所需的子网掩码

    int fd = tun_open(dev);
    if (fd < 0) return;

    // 设置 IP 地址和子网掩码
    if (set_ip_and_mask(dev, ip, mask) < 0) {
        close(fd);
        return;
    }

    log_info("创建网络接口成功,名称：%s,ip：%s，子网掩码：%s", dev, ip, mask);

    //初始map
    HashMap map;
    init_hash_map(&map);
    //启动sockets监听
    start_sockets(fd, &map);

    while (1) {

        ssize_t nread = read(fd, buffer, sizeof(buffer));
        if (nread < 0) {
            log_error("读取网络接口[%s]失败：%s", dev,strerror(errno));
            break;
        }

        if (nread < sizeof(struct iphdr)) {
            log_info("数据包长度不足，无法满足IP数据包的要求，过滤");
            continue;
        }

        struct iphdr* ip_header = (struct iphdr*)buffer;


        struct in_addr source_ip, dest_ip;
        source_ip.s_addr = ip_header->saddr;
        dest_ip.s_addr = ip_header->daddr;

        char src_ip[INET_ADDRSTRLEN]; // 为源IP分配足够的空间
        char dst_ip[INET_ADDRSTRLEN]; // 为目标IP分配足够的空间

        strcpy(src_ip, inet_ntoa(source_ip)); // 使用strcpy将结果复制到字符数组
        strcpy(dst_ip, inet_ntoa(dest_ip));


        log_debug_print(buffer, (size_t)nread);


        if (ip_header->version == 4) {

            struct tcphdr* tcp_header = (struct tcphdr*)(buffer + ip_header->ihl * 4);

            uint16_t source_port = ntohs(tcp_header->source);
            uint16_t dest_port = ntohs(tcp_header->dest);

            uint32_t seq = ntohl(tcp_header->seq);
            uint32_t ack_seq = ntohl(tcp_header->ack_seq);


            __u16  syn = tcp_header->syn;
            //__u16  ack = tcp_header->ack;
            __u16  fin = tcp_header->fin;

            // 计算 TCP 头的实际长度
            int tcp_header_len = (tcp_header->doff * 4);
            int ip_header_len = ip_header->ihl * 4;
            int total_header_len = ip_header_len + tcp_header_len;

            if (nread < total_header_len) {
                printf("Not enough data for TCP header and payload.\n");
                continue;
            }

            ssize_t data_len = nread - total_header_len;

            char dest[30];
            int result = sprintf(dest, "%s#%d", src_ip, source_port);

            if (result < 0) {
                perror("sprintf failed");
                continue;
            }

            SocketNode* socket_node = find(&map, dest);

            if (syn) {

                if (socket_node == NULL) {

                    socket_node = create_sockets(dst_ip, dest_port, src_ip, source_port, seq + 1);
                    if (socket_node != NULL) {
                        insert_or_update(&map, dest, socket_node);
                    }

                }

            }
            else {

                if (data_len > 0) {
                    //有数据需要push
                    if (socket_node != NULL && seq == socket_node->ack) {

                        char* data = (char*)(buffer + ((size_t)ip_header->ihl * 4 + sizeof(struct tcphdr)));


                        //认为写入成功
                        socket_node->ack = socket_node->ack + (unsigned int)data_len;
                        ssize_t bytes_sent = send(socket_node->fd, data, (size_t)data_len, 0);
                        if (bytes_sent < 0) {
                            if (errno == EAGAIN || errno == EWOULDBLOCK) {
                                printf("Buffer full, try again later\n");
                            }
                            else {
                                perror("Send failed");
                            }

                            //重置
                            packet_rst(fd, socket_node);

                        }
                        else {
                            if (data_len != bytes_sent) {
                                //重置
                                packet_rst(fd, socket_node);
                            }
                            else {
                                if (socket_node != NULL) {
                                    //回应ack
                                    packet_ack(fd, socket_node);

                                }
                            }

                        }

                    }
                }
                if (fin) {


                    if (socket_node != NULL) {
                        socket_node->ack += 1;
                        //回应ack
                        packet_ack(fd, socket_node);
                        close_socket_node(fd,socket_node, &map);                      

                    }
                    else {
                        SocketNode new_node;
                        new_node.seq = ack_seq;
                        new_node.ack = seq + 1;
                        new_node.src_ip = dst_ip;
                        new_node.src_port = dest_port;
                        new_node.dst_ip = src_ip;
                        new_node.dst_port = source_port;

                        //回应fin
                        packet_fin(fd, &new_node);

                    }

                }
            }

  
        }
        else if (ip_header->version == 6) {

        }
    }

    close(fd);
}

